package com.mxpio.erp.inventory.service.impl;

import com.mxpio.erp.common.enums.NoticeStatusEnums;
import com.mxpio.erp.common.inventory.entity.InitStockNotice;
import com.mxpio.erp.common.inventory.entity.InitStockNoticeLine;
import com.mxpio.erp.common.inventory.entity.Lot;
import com.mxpio.erp.common.inventory.service.InitStockNoticeService;
import com.mxpioframework.common.vo.Result;
import com.mxpioframework.jpa.JpaUtil;
import com.mxpioframework.jpa.policy.CrudContext;
import com.mxpioframework.jpa.policy.impl.SmartCrudPolicyAdapter;
import com.mxpioframework.system.service.impl.BaseServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

@Service
public class InitStockNoticeServiceImpl extends BaseServiceImpl<InitStockNotice> implements InitStockNoticeService {
    @Override
    @Transactional
    public Result<InitStockNotice> checkAndSave(InitStockNotice notice) {

        //校验提交数据的明细数据中的批次是否全局唯一
        List<InitStockNoticeLine> initStockNoticeLines = notice.getInitStockNoticeLines();
        Map<String,Integer> lotMap = new HashMap<>();
        for (InitStockNoticeLine line:initStockNoticeLines){
            String lotNo = line.getLotNo();
            if (StringUtils.isNotBlank(lotNo)){
                if (lotMap.containsKey(lotNo)){
                    Integer cnt = lotMap.get(lotNo)+1;
                    lotMap.put(lotNo,cnt);
                }else{
                    lotMap.put(lotNo,1);//默认1
                }
            }
        }
        String repeatCommitStr = "";//本次重复提交的lotno
        String repeatLotStr = "";//lot表已存在的lotno
        String repeatLineStr = "";//其他未提交的通知单明细已存在的lotno
        if (!lotMap.isEmpty()){
            Set<String> lotNoSet = lotMap.keySet();
            //先校验本次提交数据有没有重复的lotno
            for (String lotno:lotNoSet){
                Integer cnt = lotMap.get(lotno);
                if (cnt>1){
                    repeatCommitStr += lotno+";";
                }
            }

            //再校验本次提交的lotno在不在lot中存在
            List<Lot> lotList = JpaUtil.linq(Lot.class).in("lotNo", lotNoSet).list();
            if (!lotList.isEmpty()){
                for (Lot lot:lotList){
                    repeatLotStr += lot.getLotNo()+";";
                }
            }

            //最后校验未提交的初始化库存通知单明细中，是否已存在批次
            List<InitStockNoticeLine> dbNoticeLineList = JpaUtil.linq(InitStockNoticeLine.class)
                    .exists(InitStockNotice.class)
                    .equalProperty("noticeNo", "noticeNo")
                    .equal("noticeStatus", NoticeStatusEnums.NoticeStatus.CREATE.getStatusCode())
                    .end()
                    .in("lotNo", lotNoSet).list();
            if (!dbNoticeLineList.isEmpty()){
                for (InitStockNoticeLine line:dbNoticeLineList){
                    repeatLineStr += line.getLotNo()+";";
                }
            }
        }
        String errorMsg = "";
        if (StringUtils.isNotBlank(repeatCommitStr)){
            errorMsg +="提交的数据中存在重复的批次号：【"+repeatCommitStr+"】";
        }

        if (StringUtils.isNotBlank(repeatLotStr)){
            errorMsg +="提交的数据中已经在系统中存在的批次号：【"+repeatLotStr+"】";
        }
        if (StringUtils.isNotBlank(repeatLineStr)){
            errorMsg +="提交的数据中存在其他未提交通知单明细中已存在批次号：【"+repeatLineStr+"】";
        }
        if (StringUtils.isNotBlank(errorMsg)){
            return Result.error(errorMsg);
        }
        notice.setPickingType(NoticeStatusEnums.NoticeType.INIT_IN.getCode());//指定类型：初始入库
        this.save(notice,new SmartCrudPolicyAdapter(){
            @Override
            public boolean beforeInsert(CrudContext context) {
                Object o = context.getEntity();
                if(o instanceof InitStockNoticeLine){
                    InitStockNotice initStockNotice = context.getParent();
                    ((InitStockNoticeLine) o).setNoticeNo(initStockNotice.getNoticeNo());
                }
                return true;
            }
        });
        return Result.OK(notice);
    }
}
